using DatabaseMigrationTool.Models;
using Microsoft.Data.SqlClient;
using MySqlConnector;
using Npgsql;
using System.Data;
using System.Data.Common;
using System.Data.SQLite;
using System.Text;
using Dm;  // 达梦数据库引用

namespace DatabaseMigrationTool.Services
{
    public class DatabaseMigrationService
    {
        private readonly ILogger<DatabaseMigrationService> _logger;

        // 跟踪类型映射，用于生成报告
        private readonly Dictionary<string, string> _typeConversions = new Dictionary<string, string>();

        public DatabaseMigrationService(ILogger<DatabaseMigrationService> logger)
        {
            _logger = logger;
        }

        public async Task<List<string>> GetTablesAsync(DatabaseConnectionInfo connectionInfo)
        {
            var tables = new List<string>();
            var connection = CreateConnection(connectionInfo);

            try
            {
                await connection.OpenAsync();
                var query = GetTablesQuery(connectionInfo.DatabaseType, connectionInfo.Database);

                using var command = connection.CreateCommand();
                command.CommandText = query;

                using var reader = await command.ExecuteReaderAsync();
                while (await reader.ReadAsync())
                {
                    tables.Add(reader.GetString(0));
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取表列表失败");
                throw;
            }
            finally
            {
                await connection.CloseAsync();
            }

            return tables;
        }

        // 新增方法：获取表的外键关系
        public async Task<Dictionary<string, List<ForeignKeyInfo>>> GetForeignKeysForTablesAsync(
            DatabaseConnectionInfo connectionInfo,
            List<string> tables)
        {
            // 在创建连接前修改连接字符串，添加命令超时参数
            if (connectionInfo.ConnectionString == null || !connectionInfo.ConnectionString.Contains("Command Timeout"))
            {
                if (connectionInfo.DatabaseType == DatabaseType.MySql)
                {
                    connectionInfo.ConnectionString = connectionInfo.BuildConnectionString() + ";Default Command Timeout=180;";
                }
                else
                {
                    connectionInfo.ConnectionString = connectionInfo.BuildConnectionString() + ";CommandTimeout=180;";
                }
            }

            var connection = CreateConnection(connectionInfo);

            try
            {
                await connection.OpenAsync();

                // 如果没有指定表，则获取所有表
                if (tables == null || tables.Count == 0)
                {
                    tables = await GetTablesAsync(connectionInfo);
                }

                // 如果表数量过多，给出警告信息
                if (tables.Count > 50)
                {
                    _logger.LogWarning($"正在尝试获取 {tables.Count} 个表的外键关系，数量较大可能影响性能");
                }

                // 对于大量表，采用分批处理策略
                if (tables.Count > 100)
                {
                    return await GetForeignKeysBatchedAsync(connection, connectionInfo.DatabaseType, tables);
                }

                return await GetForeignKeysAsync(connection, connectionInfo.DatabaseType, tables);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取外键关系失败: {ex.Message}");

                // 添加更详细的错误信息
                if (ex.InnerException != null)
                {
                    _logger.LogError($"内部错误: {ex.InnerException.Message}");
                }

                throw new Exception($"获取外键关系失败: {ex.Message}. 可能的原因: 表数量过多、查询超时或数据库权限不足", ex);
            }
            finally
            {
                await connection.CloseAsync();
            }
        }

        public async Task<bool> MigrateAsync(DatabaseMigrationRequest request)
        {
            var sourceConnection = CreateConnection(request.SourceDatabase);
            var targetConnection = CreateConnection(request.TargetDatabase);

            try
            {
                await sourceConnection.OpenAsync();
                await targetConnection.OpenAsync();

                // 清除之前的类型转换记录
                _typeConversions.Clear();

                // 如果没有指定表，则获取所有表
                if (request.SelectedTables.Count == 0)
                {
                    request.SelectedTables = await GetTablesAsync(request.SourceDatabase);
                }

                // 获取所有外键关系（如果需要处理外键）
                Dictionary<string, List<ForeignKeyInfo>> foreignKeys = new Dictionary<string, List<ForeignKeyInfo>>();
                if (request.ProcessForeignKeys)
                {
                    _logger.LogInformation("开始获取外键关系");
                    foreignKeys = await GetForeignKeysAsync(sourceConnection, request.SourceDatabase.DatabaseType, request.SelectedTables);
                    _logger.LogInformation($"获取到 {foreignKeys.Sum(fk => fk.Value.Count)} 个外键关系");
                }

                // 记录表迁移顺序，以确保先迁移没有外键依赖的表
                if (request.ProcessForeignKeys)
                {
                    // 对表排序，以确保被引用的表先创建
                    request.SelectedTables = SortTablesByDependency(request.SelectedTables, foreignKeys);
                    _logger.LogInformation("已根据外键依赖关系对表进行排序");
                }

                // 先创建所有表结构
                foreach (var tableName in request.SelectedTables)
                {
                    _logger.LogInformation($"开始迁移表 {tableName}");

                    if (request.MigrateSchema)
                    {
                        var schema = await GetTableSchemaAsync(sourceConnection, tableName, request.SourceDatabase.DatabaseType, request.TargetDatabase.DatabaseType);
                        await CreateTableAsync(targetConnection, schema, tableName, request.TargetDatabase.DatabaseType);
                    }
                }

                // 然后创建外键关系
                if (request.ProcessForeignKeys && request.MigrateSchema)
                {
                    _logger.LogInformation("开始创建外键关系");
                    foreach (var tableEntry in foreignKeys)
                    {
                        string tableName = tableEntry.Key;
                        if (request.SelectedTables.Contains(tableName))
                        {
                            foreach (var fkInfo in tableEntry.Value)
                            {
                                // 只有当引用的表也在迁移列表中时，才创建外键
                                if (request.SelectedTables.Contains(fkInfo.ReferencedTableName))
                                {
                                    await CreateForeignKeyAsync(targetConnection, fkInfo, request.TargetDatabase.DatabaseType);
                                    _logger.LogInformation($"已创建外键关系: {fkInfo.Name}");
                                }
                            }
                        }
                    }
                }

                // 迁移数据
                if (request.MigrateData)
                {
                    foreach (var tableName in request.SelectedTables)
                    {
                        await MigrateTableDataAsync(sourceConnection, targetConnection, tableName,
                            request.SourceDatabase.DatabaseType, request.TargetDatabase.DatabaseType);
                    }
                }

                foreach (var tableName in request.SelectedTables)
                {
                    _logger.LogInformation($"表 {tableName} 迁移完成");
                }

                // 输出数据类型转换汇总
                if (request.SourceDatabase.DatabaseType != request.TargetDatabase.DatabaseType && request.MigrateSchema)
                {
                    _logger.LogInformation("数据类型转换汇总:");
                    foreach (var conversion in _typeConversions)
                    {
                        _logger.LogInformation($"  从 {conversion.Key} 转换为 {conversion.Value}");
                    }
                }

                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "迁移失败");
                throw;
            }
            finally
            {
                await sourceConnection.CloseAsync();
                await targetConnection.CloseAsync();
            }
        }

        private List<string> SortTablesByDependency(List<string> tables, Dictionary<string, List<ForeignKeyInfo>> foreignKeys)
        {
            var sortedTables = new List<string>();
            var visitedTables = new HashSet<string>();
            var temporaryMark = new HashSet<string>();

            // 深度优先搜索，确保依赖项（被引用的表）先处理
            foreach (var table in tables)
            {
                if (!visitedTables.Contains(table))
                {
                    VisitTableNode(table, tables, foreignKeys, visitedTables, temporaryMark, sortedTables);
                }
            }

            return sortedTables;
        }

        private void VisitTableNode(string table, List<string> allTables, Dictionary<string, List<ForeignKeyInfo>> foreignKeys,
            HashSet<string> visitedTables, HashSet<string> temporaryMark, List<string> sortedTables)
        {
            if (temporaryMark.Contains(table))
            {
                // 检测到循环依赖，将忽略某些外键以打破循环
                _logger.LogWarning($"检测到循环依赖关系在表 {table}，将忽略某些外键关系");
                return;
            }

            if (!visitedTables.Contains(table))
            {
                temporaryMark.Add(table);

                // 找出当前表引用的所有表
                var dependencies = new HashSet<string>();
                if (foreignKeys.ContainsKey(table))
                {
                    foreach (var fk in foreignKeys[table])
                    {
                        if (allTables.Contains(fk.ReferencedTableName) && fk.ReferencedTableName != table) // 避免自引用
                        {
                            dependencies.Add(fk.ReferencedTableName);
                        }
                    }
                }

                // 递归处理依赖的表
                foreach (var dependency in dependencies)
                {
                    VisitTableNode(dependency, allTables, foreignKeys, visitedTables, temporaryMark, sortedTables);
                }

                temporaryMark.Remove(table);
                visitedTables.Add(table);
                sortedTables.Add(table);
            }
        }

        private async Task<Dictionary<string, List<ForeignKeyInfo>>> GetForeignKeysAsync(
            DbConnection connection,
            DatabaseType databaseType,
            List<string> tables)
        {
            var foreignKeys = new Dictionary<string, List<ForeignKeyInfo>>();

            try
            {
                foreach (var table in tables)
                {
                    // 不同数据库系统获取外键的SQL不同
                    string query = GetForeignKeysQuery(databaseType, table);
                    if (string.IsNullOrEmpty(query))
                    {
                        continue; // 不支持的数据库类型
                    }

                    using var command = connection.CreateCommand();
                    command.CommandText = query;

                    using var reader = await command.ExecuteReaderAsync();
                    var tableForeignKeys = new List<ForeignKeyInfo>();

                    while (await reader.ReadAsync())
                    {
                        var fkInfo = ReadForeignKeyInfo(reader, databaseType);
                        tableForeignKeys.Add(fkInfo);
                    }

                    if (tableForeignKeys.Count > 0)
                    {
                        foreignKeys[table] = tableForeignKeys;
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取外键关系失败");
                throw;
            }

            return foreignKeys;
        }

        private string GetForeignKeysQuery(DatabaseType databaseType, string tableName)
        {
            return databaseType switch
            {
                DatabaseType.SqlServer => @$"
                    SELECT 
                        fk.name AS FK_NAME,
                        OBJECT_NAME(fk.parent_object_id) AS TABLE_NAME,
                        c.name AS COLUMN_NAME,
                        OBJECT_NAME(fk.referenced_object_id) AS REFERENCED_TABLE_NAME,
                        rc.name AS REFERENCED_COLUMN_NAME,
                        CASE WHEN fk.delete_referential_action = 1 THEN 'CASCADE'
                             WHEN fk.delete_referential_action = 2 THEN 'SET NULL'
                             WHEN fk.delete_referential_action = 3 THEN 'SET DEFAULT'
                             ELSE 'NO ACTION' END AS DELETE_RULE,
                        CASE WHEN fk.update_referential_action = 1 THEN 'CASCADE'
                             WHEN fk.update_referential_action = 2 THEN 'SET NULL'
                             WHEN fk.update_referential_action = 3 THEN 'SET DEFAULT'
                             ELSE 'NO ACTION' END AS UPDATE_RULE
                    FROM sys.foreign_keys fk
                    INNER JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id
                    INNER JOIN sys.columns c ON fkc.parent_object_id = c.object_id AND fkc.parent_column_id = c.column_id
                    INNER JOIN sys.columns rc ON fkc.referenced_object_id = rc.object_id AND fkc.referenced_column_id = rc.column_id
                    WHERE OBJECT_NAME(fk.parent_object_id) = '{tableName}'",

                DatabaseType.MySql => @$"
                    SELECT 
                        kcu.CONSTRAINT_NAME AS FK_NAME,
                        kcu.TABLE_NAME,
                        kcu.COLUMN_NAME,
                        kcu.REFERENCED_TABLE_NAME,
                        kcu.REFERENCED_COLUMN_NAME,
                        rc.DELETE_RULE,
                        rc.UPDATE_RULE
                    FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
                    JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc 
                        ON kcu.CONSTRAINT_SCHEMA = rc.CONSTRAINT_SCHEMA 
                        AND kcu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME
                    WHERE kcu.TABLE_NAME = '{tableName}' 
                        AND kcu.REFERENCED_TABLE_NAME IS NOT NULL
                        AND kcu.TABLE_SCHEMA = DATABASE()",

                DatabaseType.PostgreSql => @$"
                    SELECT
                        tc.constraint_name AS FK_NAME,
                        tc.table_name AS TABLE_NAME,
                        kcu.column_name AS COLUMN_NAME,
                        ccu.table_name AS REFERENCED_TABLE_NAME,
                        ccu.column_name AS REFERENCED_COLUMN_NAME,
                        rc.delete_rule AS DELETE_RULE,
                        rc.update_rule AS UPDATE_RULE
                    FROM information_schema.table_constraints tc
                    JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name
                    JOIN information_schema.constraint_column_usage ccu ON ccu.constraint_name = tc.constraint_name
                    JOIN information_schema.referential_constraints rc ON tc.constraint_name = rc.constraint_name
                    WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name = '{tableName}'",

                DatabaseType.Sqlite => @$"
                    SELECT 
                        fk.`id` AS FK_NAME,
                        fk.`table` AS TABLE_NAME,
                        fk.`from` AS COLUMN_NAME,
                        fk.`to` AS REFERENCED_TABLE_NAME,
                        pk.`to` AS REFERENCED_COLUMN_NAME,
                        fk.`on_delete` AS DELETE_RULE,
                        fk.`on_update` AS UPDATE_RULE
                    FROM pragma_foreign_key_list('{tableName}') fk
                    JOIN pragma_table_info('{tableName}') pk ON fk.`from` = pk.name",

                DatabaseType.DaMeng => @$"
                    SELECT 
                        a.constraint_name AS FK_NAME,
                        a.table_name AS TABLE_NAME,
                        b.column_name AS COLUMN_NAME,
                        c.table_name AS REFERENCED_TABLE_NAME,
                        c.column_name AS REFERENCED_COLUMN_NAME,
                        a.delete_rule AS DELETE_RULE,
                        a.update_rule AS UPDATE_RULE
                    FROM all_constraints a
                    JOIN all_cons_columns b ON a.constraint_name = b.constraint_name
                    JOIN all_cons_columns c ON a.r_constraint_name = c.constraint_name
                    WHERE a.constraint_type = 'R'
                    AND a.table_name = '{tableName.ToUpper()}'",

                _ => string.Empty
            };
        }

        private ForeignKeyInfo ReadForeignKeyInfo(DbDataReader reader, DatabaseType databaseType)
        {
            var fkInfo = new ForeignKeyInfo();

            if (databaseType == DatabaseType.Sqlite)
            {
                fkInfo.Name = reader["FK_NAME"].ToString() ?? "";
                fkInfo.TableName = reader["TABLE_NAME"].ToString() ?? "";
                fkInfo.ColumnName = reader["COLUMN_NAME"].ToString() ?? "";
                fkInfo.ReferencedTableName = reader["REFERENCED_TABLE_NAME"].ToString() ?? "";
                fkInfo.ReferencedColumnName = reader["REFERENCED_COLUMN_NAME"].ToString() ?? "";
                fkInfo.DeleteRule = reader["DELETE_RULE"].ToString() ?? "NO ACTION";
                fkInfo.UpdateRule = reader["UPDATE_RULE"].ToString() ?? "NO ACTION";
            }
            else
            {
                fkInfo.Name = reader["FK_NAME"].ToString() ?? "";
                fkInfo.TableName = reader["TABLE_NAME"].ToString() ?? "";
                fkInfo.ColumnName = reader["COLUMN_NAME"].ToString() ?? "";
                fkInfo.ReferencedTableName = reader["REFERENCED_TABLE_NAME"].ToString() ?? "";
                fkInfo.ReferencedColumnName = reader["REFERENCED_COLUMN_NAME"].ToString() ?? "";
                fkInfo.DeleteRule = reader["DELETE_RULE"].ToString() ?? "NO ACTION";
                fkInfo.UpdateRule = reader["UPDATE_RULE"].ToString() ?? "NO ACTION";
            }

            return fkInfo;
        }

        private async Task CreateForeignKeyAsync(DbConnection connection, ForeignKeyInfo fkInfo, DatabaseType databaseType)
        {
            try
            {
                string fkCreateSql = BuildForeignKeyStatement(fkInfo, databaseType);

                using var command = connection.CreateCommand();
                command.CommandText = fkCreateSql;
                await command.ExecuteNonQueryAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"创建外键关系 {fkInfo.Name} 失败");
                throw;
            }
        }

        private string BuildForeignKeyStatement(ForeignKeyInfo fkInfo, DatabaseType databaseType)
        {
            var fkName = string.IsNullOrEmpty(fkInfo.Name) || fkInfo.Name.StartsWith("sqlite_")
                ? $"FK_{fkInfo.TableName}_{fkInfo.ReferencedTableName}"
                : fkInfo.Name;

            var sql = $"ALTER TABLE {fkInfo.TableName} ADD CONSTRAINT {fkName} " +
                      $"FOREIGN KEY ({fkInfo.ColumnName}) " +
                      $"REFERENCES {fkInfo.ReferencedTableName} ({fkInfo.ReferencedColumnName})";

            // 添加ON DELETE和ON UPDATE规则
            if (!string.IsNullOrEmpty(fkInfo.DeleteRule) && fkInfo.DeleteRule != "NO ACTION")
            {
                sql += $" ON DELETE {fkInfo.DeleteRule}";
            }

            if (!string.IsNullOrEmpty(fkInfo.UpdateRule) && fkInfo.UpdateRule != "NO ACTION")
            {
                sql += $" ON UPDATE {fkInfo.UpdateRule}";
            }

            return sql + ";";
        }

        private DbConnection CreateConnection(DatabaseConnectionInfo connectionInfo)
        {
            var connectionString = connectionInfo.ConnectionString;
            if (string.IsNullOrEmpty(connectionString))
            {
                connectionString = connectionInfo.BuildConnectionString();

                // 对于长时间运行的命令添加超时设置
                if (connectionInfo.DatabaseType == DatabaseType.MySql && !connectionString.Contains("Command Timeout"))
                {
                    connectionString += ";Default Command Timeout=180;";
                }
                else if (!connectionString.Contains("CommandTimeout"))
                {
                    connectionString += ";CommandTimeout=180;";
                }
            }

            return connectionInfo.DatabaseType switch
            {
                DatabaseType.SqlServer => new SqlConnection(connectionString),
                DatabaseType.MySql => new MySqlConnection(connectionString),
                DatabaseType.PostgreSql => new NpgsqlConnection(connectionString),
                DatabaseType.Sqlite => new SQLiteConnection(connectionString),
                DatabaseType.DaMeng => new DmConnection(connectionString),
                _ => throw new NotImplementedException("不支持的数据库类型")
            };
        }

        private string GetTablesQuery(DatabaseType databaseType, string database)
        {
            return databaseType switch
            {
                DatabaseType.SqlServer => "SELECT name FROM sys.tables WHERE is_ms_shipped = 0;",
                DatabaseType.MySql => $"SELECT table_name FROM information_schema.tables WHERE table_schema = '{database}' AND table_type = 'BASE TABLE';",
                DatabaseType.PostgreSql => "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_type = 'BASE TABLE';",
                DatabaseType.Sqlite => "SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%';",
                DatabaseType.DaMeng => $"SELECT table_name FROM all_tables WHERE owner = '{database.ToUpper()}';",
                _ => throw new NotImplementedException("不支持的数据库类型")
            };
        }

        private async Task<string> GetTableSchemaAsync(DbConnection connection, string tableName, DatabaseType sourceDbType, DatabaseType targetDbType)
        {
            var schema = new StringBuilder();

            try
            {
                var commandText = sourceDbType switch
                {
                    DatabaseType.SqlServer => $"SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT, " +
                                              $"CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE " +
                                              $"FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '{tableName}' ORDER BY ORDINAL_POSITION;",

                    DatabaseType.MySql => $"SELECT COLUMN_NAME, DATA_TYPE, COLUMN_TYPE, IS_NULLABLE, COLUMN_DEFAULT, " +
                                         $"CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE, EXTRA " +
                                         $"FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '{tableName}' ORDER BY ORDINAL_POSITION;",

                    DatabaseType.PostgreSql => $"SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT, " +
                                               $"CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE, UDT_NAME " +
                                               $"FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '{tableName}' ORDER BY ORDINAL_POSITION;",

                    DatabaseType.Sqlite => $"PRAGMA table_info('{tableName}');",

                    DatabaseType.DaMeng => $"SELECT COLUMN_NAME, DATA_TYPE, COLUMN_TYPE, IS_NULLABLE, COLUMN_DEFAULT, " +
                                               $"CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE, EXTRA " +
                                               $"FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '{tableName}' ORDER BY ORDINAL_POSITION;",

                    _ => throw new NotImplementedException("不支持的数据库类型")
                };

                using var command = connection.CreateCommand();
                command.CommandText = commandText;

                using var reader = await command.ExecuteReaderAsync();
                var columns = new List<(string Name, string Type, string FullType, bool IsNullable, bool IsPrimaryKey, string DefaultValue)>();

                while (await reader.ReadAsync())
                {
                    if (sourceDbType == DatabaseType.Sqlite)
                    {
                        var name = reader.GetString(reader.GetOrdinal("name"));
                        var type = reader.GetString(reader.GetOrdinal("type"));
                        var notNull = reader.GetInt32(reader.GetOrdinal("notnull")) == 1;
                        var isPk = reader.GetInt32(reader.GetOrdinal("pk")) == 1;
                        var defaultValue = reader.IsDBNull(reader.GetOrdinal("dflt_value")) ? null : reader.GetString(reader.GetOrdinal("dflt_value"));
                        columns.Add((name, type, type, !notNull, isPk, defaultValue));
                    }
                    else
                    {
                        var name = reader.GetString(reader.GetOrdinal("COLUMN_NAME"));
                        var dataType = reader.GetString(reader.GetOrdinal("DATA_TYPE"));
                        var isNullable = reader.GetString(reader.GetOrdinal("IS_NULLABLE")) == "YES";
                        var defaultValue = reader.IsDBNull(reader.GetOrdinal("COLUMN_DEFAULT")) ? null : reader.GetString(reader.GetOrdinal("COLUMN_DEFAULT"));

                        // 获取完整类型定义（包含长度/精度）
                        string fullType = dataType;

                        // MySQL提供COLUMN_TYPE字段，包含完整类型定义
                        if (sourceDbType == DatabaseType.MySql && !reader.IsDBNull(reader.GetOrdinal("COLUMN_TYPE")))
                        {
                            fullType = reader.GetString(reader.GetOrdinal("COLUMN_TYPE"));
                        }
                        // 其他数据库需要组合类型和长度/精度
                        else
                        {
                            // 字符类型处理长度
                            if ((dataType.Contains("char") || dataType.Contains("binary")) && !reader.IsDBNull(reader.GetOrdinal("CHARACTER_MAXIMUM_LENGTH")))
                            {
                                var maxLength = reader.GetValue(reader.GetOrdinal("CHARACTER_MAXIMUM_LENGTH"));
                                if (maxLength != null && maxLength != DBNull.Value && Convert.ToInt64(maxLength) > 0)
                                {
                                    fullType = $"{dataType}({maxLength})";
                                }
                            }
                            // 数值类型处理精度和小数位
                            else if ((dataType == "decimal" || dataType == "numeric") &&
                                     !reader.IsDBNull(reader.GetOrdinal("NUMERIC_PRECISION")) &&
                                     !reader.IsDBNull(reader.GetOrdinal("NUMERIC_SCALE")))
                            {
                                var precision = reader.GetValue(reader.GetOrdinal("NUMERIC_PRECISION"));
                                var scale = reader.GetValue(reader.GetOrdinal("NUMERIC_SCALE"));
                                if (precision != null && precision != DBNull.Value && scale != null && scale != DBNull.Value)
                                {
                                    fullType = $"{dataType}({precision},{scale})";
                                }
                            }
                        }

                        // 主键信息需要额外查询
                        var isPk = false;
                        columns.Add((name, dataType, fullType, isNullable, isPk, defaultValue));
                    }
                }

                _logger.LogInformation($"从源数据库中读取到表 {tableName} 的 {columns.Count} 列");

                // 根据目标数据库类型生成建表语句
                schema.Append($"CREATE TABLE {tableName} (");
                for (int i = 0; i < columns.Count; i++)
                {
                    var column = columns[i];
                    schema.Append($"{column.Name} ");

                    // 获取目标数据库类型对应的数据类型（使用完整类型信息）
                    var targetDbTypeStr = GetMappedDataType(column.FullType, sourceDbType, targetDbType);
                    schema.Append(targetDbTypeStr);

                    // 添加默认值
                    if (column.DefaultValue != null)
                    {
                        // 根据目标数据库格式化默认值
                        string formattedDefault = FormatDefaultValue(column.DefaultValue, column.Type, targetDbType);
                        schema.Append($" DEFAULT {formattedDefault}");
                    }

                    if (column.IsPrimaryKey)
                    {
                        schema.Append(" PRIMARY KEY");
                    }

                    if (!column.IsNullable)
                    {
                        schema.Append(" NOT NULL");
                    }

                    if (i < columns.Count - 1)
                    {
                        schema.Append(", ");
                    }
                }
                schema.Append(");");

                _logger.LogInformation($"为表 {tableName} 生成了目标数据库 ({targetDbType}) 的建表语句");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取表 {tableName} 结构失败");
                throw;
            }

            return schema.ToString();
        }

        /// <summary>
        /// 根据目标数据库格式化默认值
        /// </summary>
        private string FormatDefaultValue(string defaultValue, string columnType, DatabaseType targetDbType)
        {
            if (string.IsNullOrEmpty(defaultValue))
            {
                return "NULL";
            }

            // 字符串类型
            if (columnType.Contains("char") || columnType.Contains("text"))
            {
                // 确保使用单引号括起来
                if (defaultValue.StartsWith("'") && defaultValue.EndsWith("'"))
                {
                    return defaultValue;
                }
                else
                {
                    return $"'{defaultValue.Replace("'", "''")}'";
                }
            }

            // 日期时间类型
            if (columnType.Contains("date") || columnType.Contains("time"))
            {
                if (targetDbType == DatabaseType.PostgreSql)
                {
                    if (defaultValue.Equals("CURRENT_TIMESTAMP", StringComparison.OrdinalIgnoreCase) ||
                        defaultValue.Equals("NOW()", StringComparison.OrdinalIgnoreCase))
                    {
                        return "CURRENT_TIMESTAMP";
                    }
                }
                else if (targetDbType == DatabaseType.MySql)
                {
                    if (defaultValue.Equals("CURRENT_TIMESTAMP", StringComparison.OrdinalIgnoreCase) ||
                        defaultValue.Equals("NOW()", StringComparison.OrdinalIgnoreCase))
                    {
                        return "CURRENT_TIMESTAMP";
                    }
                }
            }

            // 如果是NULL (数据库可能用不同的表示)
            if (defaultValue.Equals("NULL", StringComparison.OrdinalIgnoreCase))
            {
                return "NULL";
            }

            return defaultValue;
        }

        /// <summary>
        /// 获取将源数据类型映射到目标数据库类型的方法
        /// </summary>
        private string MapDataType(string sourceType, DatabaseType sourceDbType, DatabaseType targetDbType)
        {
            // 将类型转为小写以便统一处理
            var lowerSourceType = sourceType.ToLowerInvariant();

            // 如果是达梦数据库作为源
            if (sourceDbType == DatabaseType.DaMeng && targetDbType == DatabaseType.MySql)
            {
                return lowerSourceType switch
                {
                    "integer" => "int",
                    "number" => "decimal",
                    "varchar" => "varchar",
                    "varchar2" => "varchar",
                    "nvarchar" => "varchar",
                    "nvarchar2" => "varchar",
                    "char" => "char",
                    "nchar" => "char",
                    "clob" => "longtext",
                    "blob" => "longblob",
                    "date" => "datetime",
                    "timestamp" => "datetime",
                    "timestamp with local time zone" => "datetime",
                    "timestamp with time zone" => "datetime",
                    "time" => "time",
                    _ => "longtext"  // 默认映射到longtext
                };
            }
            else if (sourceDbType == DatabaseType.DaMeng && targetDbType == DatabaseType.PostgreSql)
            {
                return lowerSourceType switch
                {
                    "integer" => "integer",
                    "number" => "numeric",
                    "varchar" => "varchar",
                    "varchar2" => "varchar",
                    "nvarchar" => "varchar",
                    "nvarchar2" => "varchar",
                    "char" => "char",
                    "nchar" => "char",
                    "clob" => "text",
                    "blob" => "bytea",
                    "date" => "timestamp",
                    "timestamp" => "timestamp",
                    "timestamp with local time zone" => "timestamp with time zone",
                    "timestamp with time zone" => "timestamp with time zone",
                    "time" => "time",
                    _ => "text"  // 默认映射到text
                };
            }
            else if (sourceDbType == DatabaseType.DaMeng && targetDbType == DatabaseType.SqlServer)
            {
                return lowerSourceType switch
                {
                    "integer" => "int",
                    "number" => "decimal",
                    "varchar" => "varchar",
                    "varchar2" => "varchar",
                    "nvarchar" => "nvarchar",
                    "nvarchar2" => "nvarchar",
                    "char" => "char",
                    "nchar" => "nchar",
                    "clob" => "text",
                    "blob" => "varbinary(max)",
                    "date" => "datetime",
                    "timestamp" => "datetime2",
                    "timestamp with local time zone" => "datetimeoffset",
                    "timestamp with time zone" => "datetimeoffset",
                    "time" => "time",
                    _ => "text"  // 默认映射到text
                };
            }
            // 其他数据库作为源，达梦作为目标
            else if (sourceDbType == DatabaseType.MySql && targetDbType == DatabaseType.DaMeng)
            {
                return lowerSourceType switch
                {
                    "tinyint" => "number(3)",
                    "smallint" => "number(5)",
                    "mediumint" => "number(7)",
                    "int" => "integer",
                    "bigint" => "number(19)",
                    "float" => "number",
                    "double" => "number",
                    "decimal" => "number",
                    "char" => "char",
                    "varchar" => "varchar",
                    "tinytext" => "varchar(255)",
                    "text" => "clob",
                    "mediumtext" => "clob",
                    "longtext" => "clob",
                    "tinyblob" => "blob",
                    "blob" => "blob",
                    "mediumblob" => "blob",
                    "longblob" => "blob",
                    "date" => "date",
                    "datetime" => "timestamp",
                    "timestamp" => "timestamp",
                    "time" => "time",
                    "year" => "number(4)",
                    "json" => "clob",
                    _ => "clob"  // 默认映射到clob
                };
            }
            else if (sourceDbType == DatabaseType.PostgreSql && targetDbType == DatabaseType.DaMeng)
            {
                return lowerSourceType switch
                {
                    "smallint" => "number(5)",
                    "integer" => "integer",
                    "bigint" => "number(19)",
                    "real" => "number",
                    "double precision" => "number",
                    "numeric" => "number",
                    "decimal" => "number",
                    "char" => "char",
                    "varchar" => "varchar",
                    "text" => "clob",
                    "bytea" => "blob",
                    "date" => "date",
                    "timestamp" => "timestamp",
                    "timestamp with time zone" => "timestamp with time zone",
                    "time" => "time",
                    "time with time zone" => "time with time zone",
                    "interval" => "interval",
                    "boolean" => "number(1)",
                    "json" => "clob",
                    "jsonb" => "clob",
                    "uuid" => "varchar(36)",
                    _ => "clob"  // 默认映射到clob
                };
            }
            else if (sourceDbType == DatabaseType.SqlServer && targetDbType == DatabaseType.DaMeng)
            {
                return lowerSourceType switch
                {
                    "bit" => "number(1)",
                    "tinyint" => "number(3)",
                    "smallint" => "number(5)",
                    "int" => "integer",
                    "bigint" => "number(19)",
                    "real" => "number",
                    "float" => "number",
                    "decimal" => "number",
                    "money" => "number",
                    "smallmoney" => "number",
                    "char" => "char",
                    "varchar" => "varchar",
                    "nchar" => "nchar",
                    "nvarchar" => "nvarchar",
                    "text" => "clob",
                    "ntext" => "clob",
                    "binary" => "blob",
                    "varbinary" => "blob",
                    "image" => "blob",
                    "date" => "date",
                    "datetime" => "timestamp",
                    "datetime2" => "timestamp",
                    "smalldatetime" => "timestamp",
                    "datetimeoffset" => "timestamp with time zone",
                    "time" => "time",
                    "xml" => "clob",
                    "uniqueidentifier" => "varchar(36)",
                    _ => "clob"  // 默认映射到clob
                };
            }
            else if (sourceDbType == DatabaseType.Sqlite && targetDbType == DatabaseType.DaMeng)
            {
                return lowerSourceType switch
                {
                    "integer" => "integer",
                    "real" => "number",
                    "numeric" => "number",
                    "text" => "varchar(4000)",
                    "blob" => "blob",
                    _ => "clob"  // 默认映射到clob
                };
            }
            // MySQL到PostgreSQL的映射逻辑
            else if (sourceDbType == DatabaseType.MySql && targetDbType == DatabaseType.PostgreSql)
            {
                // 处理MySQL中特殊的整数类型带unsigned的情况
                if (lowerSourceType.Contains("unsigned"))
                {
                    if (lowerSourceType.Contains("tinyint"))
                    {
                        return "smallint";
                    }
                    else if (lowerSourceType.Contains("smallint"))
                    {
                        return "integer";
                    }
                    else if (lowerSourceType.Contains("mediumint") || lowerSourceType.Contains("int"))
                    {
                        return "bigint";
                    }
                    else if (lowerSourceType.Contains("bigint"))
                    {
                        return "numeric(20)";
                    }
                }

                // 处理tinyint(1)特殊情况
                if (lowerSourceType.Contains("tinyint(1)"))
                {
                    return "boolean";
                }

                if (lowerSourceType.StartsWith("tinyint"))
                {
                    return "smallint";
                }
                else if (lowerSourceType.StartsWith("smallint"))
                {
                    return "smallint";
                }
                else if (lowerSourceType.StartsWith("mediumint"))
                {
                    return "integer";
                }
                else if (lowerSourceType.StartsWith("int"))
                {
                    return "integer";
                }
                else if (lowerSourceType.StartsWith("bigint"))
                {
                    return "bigint";
                }
                else if (lowerSourceType.StartsWith("float"))
                {
                    return "real";
                }
                else if (lowerSourceType.StartsWith("double"))
                {
                    return "double precision";
                }
                else if (lowerSourceType.StartsWith("decimal"))
                {
                    return "numeric";
                }
                else if (lowerSourceType.StartsWith("char"))
                {
                    return "char";
                }
                else if (lowerSourceType.StartsWith("varchar"))
                {
                    return "varchar";
                }
                else if (lowerSourceType == "tinytext" || lowerSourceType == "text" || lowerSourceType == "mediumtext" || lowerSourceType == "longtext")
                {
                    return "text";
                }
                else if (lowerSourceType == "tinyblob" || lowerSourceType == "blob" || lowerSourceType == "mediumblob" || lowerSourceType == "longblob")
                {
                    return "bytea";
                }
                else if (lowerSourceType.StartsWith("binary"))
                {
                    return "bytea";
                }
                else if (lowerSourceType.StartsWith("varbinary"))
                {
                    return "bytea";
                }
                else if (lowerSourceType == "date")
                {
                    return "date";
                }
                else if (lowerSourceType.StartsWith("datetime") || lowerSourceType.StartsWith("timestamp"))
                {
                    return "timestamp";
                }
                else if (lowerSourceType == "time")
                {
                    return "time";
                }
                else if (lowerSourceType == "year")
                {
                    return "integer";
                }
                else if (lowerSourceType.StartsWith("bit"))
                {
                    return "bit";
                }
                else if (lowerSourceType == "json")
                {
                    return "jsonb";
                }
                else if (lowerSourceType.StartsWith("enum") || lowerSourceType.StartsWith("set"))
                {
                    return "text";
                }
                else
                {
                    _logger.LogWarning($"未识别的MySQL类型 {sourceType}，映射为PostgreSQL中的text类型");
                    return "text"; // 默认映射到text
                }
            }
            else if (sourceDbType == DatabaseType.PostgreSql && targetDbType == DatabaseType.MySql)
            {
                return lowerSourceType switch
                {
                    "boolean" => "tinyint(1)",
                    "smallint" => "smallint",
                    "integer" => "int",
                    "bigint" => "bigint",
                    "real" => "float",
                    "double precision" => "double",
                    "numeric" => "decimal",
                    "char" => "char",
                    "varchar" => "varchar",
                    "text" => "longtext",
                    "bytea" => "blob",
                    "date" => "date",
                    "timestamp" => "datetime",
                    "timestamp with time zone" => "datetime",
                    "time" => "time",
                    "json" => "json",
                    "jsonb" => "json",
                    "uuid" => "char(36)",
                    "xml" => "longtext",
                    _ => "longtext" // 默认映射到longtext
                };
            }
            else if (sourceDbType == DatabaseType.SqlServer && targetDbType == DatabaseType.PostgreSql)
            {
                return lowerSourceType switch
                {
                    "bit" => "boolean",
                    "tinyint" => "smallint",
                    "smallint" => "smallint",
                    "int" => "integer",
                    "bigint" => "bigint",
                    "real" => "real",
                    "float" => "double precision",
                    "decimal" => "numeric",
                    "money" => "numeric",
                    "smallmoney" => "numeric",
                    "char" => "char",
                    "varchar" => "varchar",
                    "text" => "text",
                    "nchar" => "char",
                    "nvarchar" => "varchar",
                    "ntext" => "text",
                    "binary" => "bytea",
                    "varbinary" => "bytea",
                    "image" => "bytea",
                    "date" => "date",
                    "datetime" => "timestamp",
                    "datetime2" => "timestamp",
                    "smalldatetime" => "timestamp",
                    "datetimeoffset" => "timestamp with time zone",
                    "time" => "time",
                    "xml" => "xml",
                    "uniqueidentifier" => "uuid",
                    _ => "text" // 默认映射到text
                };
            }
            else if (sourceDbType == DatabaseType.SqlServer && targetDbType == DatabaseType.MySql)
            {
                return lowerSourceType switch
                {
                    "bit" => "tinyint(1)",
                    "tinyint" => "tinyint",
                    "smallint" => "smallint",
                    "int" => "int",
                    "bigint" => "bigint",
                    "real" => "float",
                    "float" => "double",
                    "decimal" => "decimal",
                    "money" => "decimal(19,4)",
                    "smallmoney" => "decimal(10,4)",
                    "char" => "char",
                    "varchar" => "varchar",
                    "text" => "longtext",
                    "nchar" => "char",
                    "nvarchar" => "varchar",
                    "ntext" => "longtext",
                    "binary" => "binary",
                    "varbinary" => "varbinary",
                    "image" => "longblob",
                    "date" => "date",
                    "datetime" => "datetime",
                    "datetime2" => "datetime",
                    "smalldatetime" => "datetime",
                    "datetimeoffset" => "datetime",
                    "time" => "time",
                    "xml" => "longtext",
                    "uniqueidentifier" => "char(36)",
                    _ => "longtext" // 默认映射到longtext
                };
            }

            // 如果源数据库和目标数据库是同一种类型，或没有明确的映射规则，则保持原样
            return sourceType;
        }

        /// <summary>
        /// 获取建表语句中使用的数据类型（处理长度、精度等）
        /// </summary>
        private string GetMappedDataType(string originalType, DatabaseType sourceDbType, DatabaseType targetDbType)
        {
            // 如果源类型和目标类型相同，则不需要转换
            if (sourceDbType == targetDbType)
            {
                return originalType;
            }

            try
            {
                // 需要处理带括号的情况，如varchar(255)
                string baseType;
                string parameters = string.Empty;

                int bracketIndex = originalType.IndexOf('(');
                if (bracketIndex > 0)
                {
                    baseType = originalType.Substring(0, bracketIndex).Trim().ToLowerInvariant();
                    int closeBracketIndex = originalType.LastIndexOf(')');
                    if (closeBracketIndex > bracketIndex)
                    {
                        parameters = originalType.Substring(bracketIndex + 1, closeBracketIndex - bracketIndex - 1);
                    }
                }
                else
                {
                    baseType = originalType.Trim().ToLowerInvariant();
                }

                // 映射基本类型
                string mappedBaseType = MapDataType(baseType, sourceDbType, targetDbType);

                // 用于存储最终映射结果的变量
                string mappedResult;

                // 特殊处理某些类型
                if (sourceDbType == DatabaseType.MySql && targetDbType == DatabaseType.PostgreSql)
                {
                    // 处理MySQL中的文本类型
                    if (baseType == "varchar" || baseType == "char")
                    {
                        if (!string.IsNullOrEmpty(parameters))
                        {
                            mappedResult = $"{mappedBaseType}({parameters})";
                        }
                        else
                        {
                            mappedResult = mappedBaseType;
                        }
                    }
                    else if (baseType == "tinytext" || baseType == "text" || baseType == "mediumtext" || baseType == "longtext")
                    {
                        mappedResult = "text";
                    }
                    else if (baseType == "enum" || baseType == "set")
                    {
                        mappedResult = "text";
                    }
                    else if (baseType == "int" || baseType == "tinyint" || baseType == "smallint" || baseType == "mediumint" || baseType == "bigint")
                    {
                        // 对于整数类型，通常不需要传递长度参数，只需要类型映射
                        mappedResult = mappedBaseType;
                    }
                    else if (baseType == "double" || baseType == "float")
                    {
                        if (!string.IsNullOrEmpty(parameters) && parameters.Contains(","))
                        {
                            var parts = parameters.Split(',');
                            mappedResult = $"{mappedBaseType}({parts[0].Trim()})";
                        }
                        else
                        {
                            mappedResult = mappedBaseType;
                        }
                    }
                    else if (baseType == "decimal")
                    {
                        if (!string.IsNullOrEmpty(parameters))
                        {
                            mappedResult = $"{mappedBaseType}({parameters})";
                        }
                        else
                        {
                            mappedResult = mappedBaseType;
                        }
                    }
                    else
                    {
                        // 如果有参数并且映射后的类型支持长度/精度，则添加参数
                        if (!string.IsNullOrEmpty(parameters) && SupportsPrecision(mappedBaseType))
                        {
                            mappedResult = $"{mappedBaseType}({parameters})";
                        }
                        else
                        {
                            mappedResult = mappedBaseType;
                        }
                    }
                }
                else
                {
                    // 如果有参数并且映射后的类型支持长度/精度，则添加参数
                    if (!string.IsNullOrEmpty(parameters) && SupportsPrecision(mappedBaseType))
                    {
                        mappedResult = $"{mappedBaseType}({parameters})";
                    }
                    else
                    {
                        mappedResult = mappedBaseType;
                    }
                }

                // 记录类型转换（如果发生了转换）
                if (originalType.ToLowerInvariant() != mappedResult.ToLowerInvariant())
                {
                    string key = $"{originalType} ({sourceDbType})";
                    string value = $"{mappedResult} ({targetDbType})";

                    if (!_typeConversions.ContainsKey(key))
                    {
                        _typeConversions[key] = value;
                        _logger.LogInformation($"数据类型映射: {key} -> {value}");
                    }
                }

                return mappedResult;
            }
            catch (Exception ex)
            {
                _logger.LogWarning($"类型映射失败 {originalType}: {ex.Message}，使用基本映射");
                return MapDataType(originalType, sourceDbType, targetDbType);
            }
        }

        /// <summary>
        /// 判断数据类型是否支持长度/精度
        /// </summary>
        private bool SupportsPrecision(string typeName)
        {
            // 这些类型通常支持长度或精度
            return typeName.ToLowerInvariant() switch
            {
                "varchar" or "char" or "decimal" or "numeric" or "real" or "float" or "double precision" => true,
                _ => false
            };
        }

        private async Task CreateTableAsync(DbConnection connection, string createTableSql, string tableName, DatabaseType databaseType)
        {
            try
            {
                // 检查表是否已存在
                var checkTableExists = databaseType switch
                {
                    DatabaseType.SqlServer => $"IF OBJECT_ID('{tableName}', 'U') IS NOT NULL SELECT 1 ELSE SELECT 0;",
                    DatabaseType.MySql => $"SELECT COUNT(*) FROM information_schema.tables WHERE table_name = '{tableName}';",
                    DatabaseType.PostgreSql => $"SELECT COUNT(*) FROM information_schema.tables WHERE table_name = '{tableName}';",
                    DatabaseType.Sqlite => $"SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='{tableName}';",
                    DatabaseType.DaMeng => $"SELECT COUNT(*) FROM all_tables WHERE table_name = '{tableName.ToUpper()}';",
                    _ => throw new NotImplementedException("不支持的数据库类型")
                };

                using var checkCommand = connection.CreateCommand();
                checkCommand.CommandText = checkTableExists;
                var exists = Convert.ToInt32(await checkCommand.ExecuteScalarAsync()) > 0;

                if (exists)
                {
                    // 如果表已存在，则删除
                    var dropTable = $"DROP TABLE {tableName};";
                    using var dropCommand = connection.CreateCommand();
                    dropCommand.CommandText = dropTable;
                    await dropCommand.ExecuteNonQueryAsync();
                }

                // 创建表
                using var createCommand = connection.CreateCommand();
                createCommand.CommandText = createTableSql;
                await createCommand.ExecuteNonQueryAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"创建表 {tableName} 失败");
                throw;
            }
        }

        private async Task MigrateTableDataAsync(
            DbConnection sourceConnection,
            DbConnection targetConnection,
            string tableName,
            DatabaseType sourceDbType,
            DatabaseType targetDbType)
        {
            try
            {
                // 获取源表数据
                using var sourceCommand = sourceConnection.CreateCommand();
                sourceCommand.CommandText = $"SELECT * FROM {tableName};";

                using var reader = await sourceCommand.ExecuteReaderAsync();
                var dataTable = new DataTable();
                dataTable.Load(reader);

                // 如果没有数据，直接返回
                if (dataTable.Rows.Count == 0)
                {
                    _logger.LogInformation($"表 {tableName} 没有数据需要迁移");
                    return;
                }

                // 构建插入语句
                var columns = string.Join(", ", dataTable.Columns.Cast<DataColumn>().Select(c => c.ColumnName));
                var values = string.Join(", ", dataTable.Columns.Cast<DataColumn>().Select(c => $"@{c.ColumnName}"));

                using var transaction = await targetConnection.BeginTransactionAsync();

                try
                {
                    // 批量插入数据
                    foreach (DataRow row in dataTable.Rows)
                    {
                        using var insertCommand = targetConnection.CreateCommand();
                        insertCommand.Transaction = transaction;
                        insertCommand.CommandText = $"INSERT INTO {tableName} ({columns}) VALUES ({values});";

                        foreach (DataColumn column in dataTable.Columns)
                        {
                            var parameter = insertCommand.CreateParameter();
                            parameter.ParameterName = $"@{column.ColumnName}";
                            parameter.Value = row[column] ?? DBNull.Value;
                            insertCommand.Parameters.Add(parameter);
                        }

                        await insertCommand.ExecuteNonQueryAsync();
                    }

                    await transaction.CommitAsync();
                    _logger.LogInformation($"表 {tableName} 的 {dataTable.Rows.Count} 条数据已迁移完成");
                }
                catch (Exception ex)
                {
                    await transaction.RollbackAsync();
                    _logger.LogError(ex, $"迁移表 {tableName} 数据失败");
                    throw;
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"迁移表 {tableName} 数据失败");
                throw;
            }
        }

        // 分批处理大量表的外键关系
        private async Task<Dictionary<string, List<ForeignKeyInfo>>> GetForeignKeysBatchedAsync(
            DbConnection connection,
            DatabaseType databaseType,
            List<string> tables)
        {
            const int batchSize = 20; // 每批处理20个表
            var result = new Dictionary<string, List<ForeignKeyInfo>>();

            // 分批处理
            for (int i = 0; i < tables.Count; i += batchSize)
            {
                var batch = tables.Skip(i).Take(batchSize).ToList();
                _logger.LogInformation($"处理表外键关系批次 {i / batchSize + 1}/{(tables.Count + batchSize - 1) / batchSize}, 包含 {batch.Count} 个表");

                try
                {
                    var batchResults = await GetForeignKeysAsync(connection, databaseType, batch);

                    // 合并结果
                    foreach (var tableEntry in batchResults)
                    {
                        result[tableEntry.Key] = tableEntry.Value;
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, $"处理表批次 {i / batchSize + 1} 失败，跳过这批表: {string.Join(", ", batch)}");
                }
            }

            return result;
        }
    }
}